﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using WindowsLive.Writer.Api;

namespace DeliciousPlugin
{
    public class PluginSettings
    {
        private IProperties m_properties;
        private const string USERNAME = "USERNAME";
        private const string PASSWORD = "PASSWORD";
        private const string AUTOPOST = "AUTOPOST";

        public PluginSettings(IProperties properties)
        {
            m_properties = properties;
        }

        public string UserName
        {
            get { return Decrypt(m_properties.GetString(USERNAME, "")); }
            set { m_properties.SetString(USERNAME, Encrypt(value)); }
        }

        public string Password
        {
            get { return Decrypt(m_properties.GetString(PASSWORD, "")); }
            set { m_properties.SetString(PASSWORD, Encrypt(value)); }
        }

        public bool AutomaticallyPost
        {
            get { return m_properties.GetBoolean(AUTOPOST, false); }
            set { m_properties.SetBoolean(AUTOPOST, value); }
        }

        /// <summary>
        /// Encrypt a string using DPAPI.
        /// </summary>
        private static string Encrypt(string s)
        {
            if (string.IsNullOrEmpty(s))
                return string.Empty;

            byte[] entropy = new byte[16];

            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(entropy);

            byte[] secretBytes = Encoding.Unicode.GetBytes(s);
            byte[] encrypted = ProtectedData.Protect(
                secretBytes, entropy, DataProtectionScope.CurrentUser);

            byte[] package = new byte[entropy.Length + encrypted.Length];
            Array.Copy(entropy, package, 16);
            Array.Copy(encrypted, 0, package, 16, encrypted.Length);

            return Convert.ToBase64String(package);
        }

        /// <summary>
        /// Decrypt a string using DPAPI.
        /// </summary>
        private static string Decrypt(string s)
        {
            if (string.IsNullOrEmpty(s))
                return string.Empty;

            try
            {
                byte[] package = Convert.FromBase64String(s);
                byte[] entropy = new byte[16];
                byte[] encrypted = new byte[package.Length - 16];
                Array.Copy(package, entropy, 16);
                Array.Copy(package, 16, encrypted, 0, encrypted.Length);

                byte[] secretBytes = ProtectedData.Unprotect(
                    encrypted, entropy, DataProtectionScope.CurrentUser);
                return Encoding.Unicode.GetString(secretBytes);
            }
            catch (FormatException)
            {
                return null;
            }
            catch (CryptographicException)
            {
                return null;
            }
        }
    }
}
